#include <iostream>
#include "miniutil/strutil.h"
#include "miniutil/srpc.h"

class RemoteCmdHandler:public miniutil::frame::RpcNodeHandler
{
public:
    void showRpcMsg(miniutil::frame::ShareRpcMsg smsg)
    {
        for(int i=0; i< smsg->mvparas.size(); i++)
        {
            std::cout<<(std::string)(*smsg->mvparas[i])<<" ";
        }
        std::cout<<std::endl;
    }

    virtual int operator()(miniutil::frame::RpcNode* pnode)
    {
        if(pnode->mvremotereqmsgs.size() > 0)
        {
            std::cout<<"REQ MSG:"<<pnode->mvremotereqmsgs.size()<<std::endl;
            for(int i=0; i< pnode->mvremotereqmsgs.size(); i++)
            {
                miniutil::frame::ShareRpcMsg smsg = pnode->mvremotereqmsgs[i];
                showRpcMsg(smsg);
                if(std::string(*smsg->mvparas[0]) == "print")
                {
                    miniutil::frame::ShareRpcMsg rtnsmsg = miniutil::frame::ShareRpcMsg::safenew("print", 1);
                    //.. is there any suggestion that set msgtype more explicit?
                    rtnsmsg->mmsgtype = miniutil::frame::RpcMessage::RESP;
                    rtnsmsg->ssessid = smsg->ssessid;
                    pnode->invoke(rtnsmsg, false);
                }
            }
            pnode->mvremotereqmsgs.clear();
        }
        if(pnode->mvremoterespmsgs.size() > 0)
        {
            std::cout<<"RESP MSG:"<<pnode->mvremoterespmsgs.size()<<std::endl;
            std::map<int, miniutil::frame::ShareRpcMsg>::iterator iter_mis;
            for(iter_mis = pnode->mvremoterespmsgs.begin();
                iter_mis != pnode->mvremoterespmsgs.end();
                iter_mis ++)
            {
                showRpcMsg(iter_mis->second);
            }
            pnode->mvremoterespmsgs.clear();
        }
        return 0;
    }
};

class DoWithNode:public miniutil::frame::ThreadService
{
public:
    DoWithNode(miniutil::frame::RpcService* pservice)
    {
        mps = pservice;
    }

    virtual int WorkingTask()
    {
        mps->checkNode(&mhandler);
        return 0;
    }

private:
    miniutil::frame::RpcService* mps;
    RemoteCmdHandler mhandler;

};

//command sample:
//127.0.0.1:1112 play abc
int main(int argc, char** argv)
{
    unsigned short port = 0;
    if(argc >= 2)
       port = atoi(argv[1]);

    miniutil::frame::RpcService rpcservice(port);

    DoWithNode nodeservice(&rpcservice);
    nodeservice.Start();
    rpcservice.Start();
    while(true)
    {
        std::string cmd;
        std::cout<<">>";
        ::getline(std::cin, cmd);
        if(cmd == "exit")
        {
            std::cout<<std::endl;
            break;
        }
        std::vector<std::string> vcmds;
        vcmds = miniutil::strutil::split(cmd, " ");
        if(vcmds.size() < 2)
        {
            std::cout<<std::endl;
            continue;
        }
        miniutil::soaddr addr(vcmds[0]);
        vcmds.erase(vcmds.begin());
        miniutil::frame::RpcNode* pnode = rpcservice.GetPeer(addr);
        if(pnode != NULL)
        {
            miniutil::frame::ShareRpcMsg smsg = miniutil::frame::ShareRpcMsg::safenew(vcmds);
            //miniutil::frame::ShareRpcMsg smsg = miniutil::frame::ShareRpcMsg::safenew("working",2,3);
            pnode->invoke(smsg, false);
        }
        std::cout<<std::endl;
    }
    rpcservice.Stop();
    nodeservice.Stop();
}

